var events = require('events');
var inputEvent = new events.EventEmitter();
var configEvent=new events.EventEmitter()
// const Gpio = require('onoff').Gpio
const Gpio = require('./cycle').Gpio
const SerialPort = require('serialport')
const db = require('./db')
var triggerPort, addPort, deletePort, serialPort, frame

var load = (cb) => {
    console.log('开始加载')
    db.syncTables(() => {
        console.log('同步完成')
        db.getConfigInfo((data) => {
            console.log(data)
            updateAllConfig(data, (err) => {
                if (cb) cb(err)
            })
        })
    })
}

//触发端口
var getTrigPort = () => { return triggerPort }
var setTrigPort = (port, cb) => {
    try {
        if (typeof triggerPort == Object) {
            // triggerPort.writeSync(0)
            // triggerPort.unexport()
            triggerPort.write(0).then(triggerPort.unexport())
        }
        triggerPort = new Gpio(port, 'out')
        if (cb) cb()
    } catch (error) {
        console.log(error)
        if (cb) cb("触发端口配置错误")
    }
}

//添加记录端口
var getAddPort = () => { return addPort }
var setAddPort = (port, cb) => {
    try {
        if (typeof addPort == Object) addPort.unexport()
        addPort = new Gpio(port, 'in', 'falling', { debounceTimeout: 100 })
        addPort.watch((err, value) => { inputEvent.emit('add', value) })
        if (cb) cb()
    } catch (error) {
        console.log(error)
        if (cb) cb("添加按钮配置错误")
    }
}

//删除记录端口
var getDeletePort = () => { return deletePort }
var setDeletePort = (port, cb) => {
    try {
        if (typeof deletePort == Object) deletePort.unexport()
        deletePort = new Gpio(port, 'in', 'falling', { debounceTimeout: 100 })
        deletePort.watch((err, value) => { inputEvent.emit('delete', value) })
        if (cb) cb()
    } catch (error) {
        console.log(error)
        if (cb) cb("删除按钮配置错误")
    }
}

//串口
var getSerialPort = () => { return serialPort }
var setSerialPort = (path, params, cb) => {
    try {
        if (serialPort && serialPort.isOpen)
            serialPort.close();
        serialPort = new SerialPort(path, {
            baudRate: params.baudRate || 9600,
            dataBits: params.dataBits || 8,
            stopBits: params.stopBits || 1,
            parity: params.parity || 'none',
            autoOpen: false
        })
        if (cb) cb()
    } catch (error) {
        console.log(error)
        if (cb) cb("串口配置错误")
    }
}

//数据帧格式
var getFrame = () => { return frame }
var setFrame = (frameName, cb) => {
    try {
        frame = require(`./frame/${frameName}`)
        if (cb) cb()
    } catch (error) {
        console.log(error)
        if (cb) cb("数据帧配置错误")
    }
}

//获取所有串口信息
var getAllSerialPort = (cb) => {
    SerialPort.list().then((ports) => {
        cb(ports)
    })
}

//获取配置信息
var getConfigInfo = () => {
    return {
        triggerPort: triggerPort._gpio,
        addPort: addPort._gpio,
        deletePort: deletePort._gpio,
        frame: frame.name,
        serialPort: {
            serialPath: serialPort.path,
            baudRate: serialPort.settings.baudRate,
            dataBits: serialPort.settings.dataBits,
            parity: serialPort.settings.parity,
            stopBits: serialPort.settings.stopBits
        }
    }
}

//更新配置
var updateConfig = (values, cb) => {
    // console.log(values)
    var options = { where: { id: 1 } }
    db.updateConfig(values, options, (num) => {
        console.log(num)
        if (num > 0) {
            updateAllConfig(values)
            if (cb) cb()
        }
        else if (cb) cb("更新config表错误")
    })
}

//更新所有配置
var updateAllConfig = (values, cb) => {
    console.log("**********")
    var trig = values.triggerPort
    var add = values.addPort
    var del = values.deletePort
    var frameName = values.frame
    var serialPath = values.serialPath
    var msg
    if (trig && (!triggerPort || trig != triggerPort._gpio)) setTrigPort(trig, (err) => {
        if (err) msg = err
    })
    if (add && (!addPort || add != addPort._gpio)) setAddPort(add, (err) => {
        if (err) msg = msg + "," + err
    })
    if (del && (!deletePort || del != deletePort._gpio)) setDeletePort(del, (err) => {
        if (err) msg = msg + "," + err
    })
    if (frameName && (!frame || frameName != frame.name)) setFrame(frameName, (err) => {
        if (err) msg = msg + "," + err
    })
    if (serialPath && (!serialPort || serialPath != serialPort.path)) {
        console.log('开始配置串口')
        db.getSerialInfo(serialPath, (data) => {
            setSerialPort(serialPath, data, (err) => {
                if (err) msg = msg + "," + err
                configEvent.emit('configed')
                if (cb) cb(msg)
            })
        })
    } else{
        configEvent.emit('configed')
        if (cb) cb(msg)
    }
       
}

//更新串口配置
var updateSerialInfo = (values, cb) => {
    var options = { where: { serialPath: serialPort.path } }
    db.updateSerialInfo(values, options, (num) => {
        if (num > 0) {
            db.getSerialInfo(serialPort.path, (data) => {
                setSerialPort(serialPort.path, data)
            })
            if (cb) cb(true)
        }
        else if (cb) cb(false)
    })
}

module.exports = {
    getTrigPort,
    getAddPort,
    getDeletePort,
    getSerialPort,
    getAllSerialPort,
    inputEvent,
    configEvent,
    getFrame,
    load,
    getConfigInfo,
    updateConfig,
    updateSerialInfo
}